// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Serverless.Core;
using Elastic.Clients.Elasticsearch.Serverless.Fluent;
using Elastic.Clients.Elasticsearch.Serverless.Serialization;
using Elastic.Transport;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.Serverless.Analysis;

public partial class Tokenizers : IsADictionary<string, ITokenizer>
{
	public Tokenizers()
	{
	}

	public Tokenizers(IDictionary<string, ITokenizer> container) : base(container)
	{
	}

	public void Add(string name, ITokenizer tokenizer) => BackingDictionary.Add(Sanitize(name), tokenizer);
	public bool TryGetTokenizer(string name, [NotNullWhen(returnValue: true)] out ITokenizer tokenizer) => BackingDictionary.TryGetValue(Sanitize(name), out tokenizer);

	public bool TryGetTokenizer<T>(string name, [NotNullWhen(returnValue: true)] out T? tokenizer) where T : class, ITokenizer
	{
		if (BackingDictionary.TryGetValue(Sanitize(name), out var matchedValue) && matchedValue is T finalValue)
		{
			tokenizer = finalValue;
			return true;
		}

		tokenizer = null;
		return false;
	}
}

public sealed partial class TokenizersDescriptor : IsADictionaryDescriptor<TokenizersDescriptor, Tokenizers, string, ITokenizer>
{
	public TokenizersDescriptor() : base(new Tokenizers())
	{
	}

	public TokenizersDescriptor(Tokenizers tokenizers) : base(tokenizers ?? new Tokenizers())
	{
	}

	public TokenizersDescriptor CharGroup(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.CharGroupTokenizerDescriptor, CharGroupTokenizer>(tokenizerName, null);
	public TokenizersDescriptor CharGroup(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.CharGroupTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.CharGroupTokenizerDescriptor, CharGroupTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor CharGroup(string tokenizerName, CharGroupTokenizer charGroupTokenizer) => AssignVariant(tokenizerName, charGroupTokenizer);
	public TokenizersDescriptor Classic(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.ClassicTokenizerDescriptor, ClassicTokenizer>(tokenizerName, null);
	public TokenizersDescriptor Classic(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.ClassicTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.ClassicTokenizerDescriptor, ClassicTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor Classic(string tokenizerName, ClassicTokenizer classicTokenizer) => AssignVariant(tokenizerName, classicTokenizer);
	public TokenizersDescriptor EdgeNGram(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.EdgeNGramTokenizerDescriptor, EdgeNGramTokenizer>(tokenizerName, null);
	public TokenizersDescriptor EdgeNGram(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.EdgeNGramTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.EdgeNGramTokenizerDescriptor, EdgeNGramTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor EdgeNGram(string tokenizerName, EdgeNGramTokenizer edgeNGramTokenizer) => AssignVariant(tokenizerName, edgeNGramTokenizer);
	public TokenizersDescriptor Icu(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.IcuTokenizerDescriptor, IcuTokenizer>(tokenizerName, null);
	public TokenizersDescriptor Icu(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.IcuTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.IcuTokenizerDescriptor, IcuTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor Icu(string tokenizerName, IcuTokenizer icuTokenizer) => AssignVariant(tokenizerName, icuTokenizer);
	public TokenizersDescriptor Keyword(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.KeywordTokenizerDescriptor, KeywordTokenizer>(tokenizerName, null);
	public TokenizersDescriptor Keyword(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.KeywordTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.KeywordTokenizerDescriptor, KeywordTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor Keyword(string tokenizerName, KeywordTokenizer keywordTokenizer) => AssignVariant(tokenizerName, keywordTokenizer);
	public TokenizersDescriptor Kuromoji(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.KuromojiTokenizerDescriptor, KuromojiTokenizer>(tokenizerName, null);
	public TokenizersDescriptor Kuromoji(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.KuromojiTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.KuromojiTokenizerDescriptor, KuromojiTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor Kuromoji(string tokenizerName, KuromojiTokenizer kuromojiTokenizer) => AssignVariant(tokenizerName, kuromojiTokenizer);
	public TokenizersDescriptor Letter(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.LetterTokenizerDescriptor, LetterTokenizer>(tokenizerName, null);
	public TokenizersDescriptor Letter(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.LetterTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.LetterTokenizerDescriptor, LetterTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor Letter(string tokenizerName, LetterTokenizer letterTokenizer) => AssignVariant(tokenizerName, letterTokenizer);
	public TokenizersDescriptor Lowercase(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.LowercaseTokenizerDescriptor, LowercaseTokenizer>(tokenizerName, null);
	public TokenizersDescriptor Lowercase(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.LowercaseTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.LowercaseTokenizerDescriptor, LowercaseTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor Lowercase(string tokenizerName, LowercaseTokenizer lowercaseTokenizer) => AssignVariant(tokenizerName, lowercaseTokenizer);
	public TokenizersDescriptor NGram(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.NGramTokenizerDescriptor, NGramTokenizer>(tokenizerName, null);
	public TokenizersDescriptor NGram(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.NGramTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.NGramTokenizerDescriptor, NGramTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor NGram(string tokenizerName, NGramTokenizer nGramTokenizer) => AssignVariant(tokenizerName, nGramTokenizer);
	public TokenizersDescriptor Nori(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.NoriTokenizerDescriptor, NoriTokenizer>(tokenizerName, null);
	public TokenizersDescriptor Nori(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.NoriTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.NoriTokenizerDescriptor, NoriTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor Nori(string tokenizerName, NoriTokenizer noriTokenizer) => AssignVariant(tokenizerName, noriTokenizer);
	public TokenizersDescriptor PathHierarchy(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.PathHierarchyTokenizerDescriptor, PathHierarchyTokenizer>(tokenizerName, null);
	public TokenizersDescriptor PathHierarchy(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.PathHierarchyTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.PathHierarchyTokenizerDescriptor, PathHierarchyTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor PathHierarchy(string tokenizerName, PathHierarchyTokenizer pathHierarchyTokenizer) => AssignVariant(tokenizerName, pathHierarchyTokenizer);
	public TokenizersDescriptor Pattern(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.PatternTokenizerDescriptor, PatternTokenizer>(tokenizerName, null);
	public TokenizersDescriptor Pattern(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.PatternTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.PatternTokenizerDescriptor, PatternTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor Pattern(string tokenizerName, PatternTokenizer patternTokenizer) => AssignVariant(tokenizerName, patternTokenizer);
	public TokenizersDescriptor SimplePatternSplit(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.SimplePatternSplitTokenizerDescriptor, SimplePatternSplitTokenizer>(tokenizerName, null);
	public TokenizersDescriptor SimplePatternSplit(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.SimplePatternSplitTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.SimplePatternSplitTokenizerDescriptor, SimplePatternSplitTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor SimplePatternSplit(string tokenizerName, SimplePatternSplitTokenizer simplePatternSplitTokenizer) => AssignVariant(tokenizerName, simplePatternSplitTokenizer);
	public TokenizersDescriptor SimplePattern(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.SimplePatternTokenizerDescriptor, SimplePatternTokenizer>(tokenizerName, null);
	public TokenizersDescriptor SimplePattern(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.SimplePatternTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.SimplePatternTokenizerDescriptor, SimplePatternTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor SimplePattern(string tokenizerName, SimplePatternTokenizer simplePatternTokenizer) => AssignVariant(tokenizerName, simplePatternTokenizer);
	public TokenizersDescriptor Standard(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.StandardTokenizerDescriptor, StandardTokenizer>(tokenizerName, null);
	public TokenizersDescriptor Standard(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.StandardTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.StandardTokenizerDescriptor, StandardTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor Standard(string tokenizerName, StandardTokenizer standardTokenizer) => AssignVariant(tokenizerName, standardTokenizer);
	public TokenizersDescriptor Thai(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.ThaiTokenizerDescriptor, ThaiTokenizer>(tokenizerName, null);
	public TokenizersDescriptor Thai(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.ThaiTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.ThaiTokenizerDescriptor, ThaiTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor Thai(string tokenizerName, ThaiTokenizer thaiTokenizer) => AssignVariant(tokenizerName, thaiTokenizer);
	public TokenizersDescriptor UaxEmailUrl(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.UaxEmailUrlTokenizerDescriptor, UaxEmailUrlTokenizer>(tokenizerName, null);
	public TokenizersDescriptor UaxEmailUrl(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.UaxEmailUrlTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.UaxEmailUrlTokenizerDescriptor, UaxEmailUrlTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor UaxEmailUrl(string tokenizerName, UaxEmailUrlTokenizer uaxEmailUrlTokenizer) => AssignVariant(tokenizerName, uaxEmailUrlTokenizer);
	public TokenizersDescriptor Whitespace(string tokenizerName) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.WhitespaceTokenizerDescriptor, WhitespaceTokenizer>(tokenizerName, null);
	public TokenizersDescriptor Whitespace(string tokenizerName, Action<Elastic.Clients.Elasticsearch.Serverless.Analysis.WhitespaceTokenizerDescriptor> configure) => AssignVariant<Elastic.Clients.Elasticsearch.Serverless.Analysis.WhitespaceTokenizerDescriptor, WhitespaceTokenizer>(tokenizerName, configure);
	public TokenizersDescriptor Whitespace(string tokenizerName, WhitespaceTokenizer whitespaceTokenizer) => AssignVariant(tokenizerName, whitespaceTokenizer);
}

internal sealed partial class TokenizerInterfaceConverter : JsonConverter<ITokenizer>
{
	public override ITokenizer Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		var copiedReader = reader;
		string? type = null;
		using var jsonDoc = JsonDocument.ParseValue(ref copiedReader);
		if (jsonDoc is not null && jsonDoc.RootElement.TryGetProperty("type", out var readType) && readType.ValueKind == JsonValueKind.String)
		{
			type = readType.ToString();
		}

		switch (type)
		{
			case "char_group":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.CharGroupTokenizer>(ref reader, options);
			case "classic":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.ClassicTokenizer>(ref reader, options);
			case "edge_ngram":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.EdgeNGramTokenizer>(ref reader, options);
			case "icu_tokenizer":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.IcuTokenizer>(ref reader, options);
			case "keyword":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.KeywordTokenizer>(ref reader, options);
			case "kuromoji_tokenizer":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.KuromojiTokenizer>(ref reader, options);
			case "letter":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.LetterTokenizer>(ref reader, options);
			case "lowercase":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.LowercaseTokenizer>(ref reader, options);
			case "ngram":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.NGramTokenizer>(ref reader, options);
			case "nori_tokenizer":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.NoriTokenizer>(ref reader, options);
			case "path_hierarchy":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.PathHierarchyTokenizer>(ref reader, options);
			case "pattern":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.PatternTokenizer>(ref reader, options);
			case "simple_pattern_split":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.SimplePatternSplitTokenizer>(ref reader, options);
			case "simple_pattern":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.SimplePatternTokenizer>(ref reader, options);
			case "standard":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.StandardTokenizer>(ref reader, options);
			case "thai":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.ThaiTokenizer>(ref reader, options);
			case "uax_url_email":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.UaxEmailUrlTokenizer>(ref reader, options);
			case "whitespace":
				return JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Analysis.WhitespaceTokenizer>(ref reader, options);
			default:
				ThrowHelper.ThrowUnknownTaggedUnionVariantJsonException(type, typeof(ITokenizer));
				return null;
		}
	}

	public override void Write(Utf8JsonWriter writer, ITokenizer value, JsonSerializerOptions options)
	{
		if (value is null)
		{
			writer.WriteNullValue();
			return;
		}

		switch (value.Type)
		{
			case "char_group":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.CharGroupTokenizer), options);
				return;
			case "classic":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.ClassicTokenizer), options);
				return;
			case "edge_ngram":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.EdgeNGramTokenizer), options);
				return;
			case "icu_tokenizer":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.IcuTokenizer), options);
				return;
			case "keyword":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.KeywordTokenizer), options);
				return;
			case "kuromoji_tokenizer":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.KuromojiTokenizer), options);
				return;
			case "letter":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.LetterTokenizer), options);
				return;
			case "lowercase":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.LowercaseTokenizer), options);
				return;
			case "ngram":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.NGramTokenizer), options);
				return;
			case "nori_tokenizer":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.NoriTokenizer), options);
				return;
			case "path_hierarchy":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.PathHierarchyTokenizer), options);
				return;
			case "pattern":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.PatternTokenizer), options);
				return;
			case "simple_pattern_split":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.SimplePatternSplitTokenizer), options);
				return;
			case "simple_pattern":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.SimplePatternTokenizer), options);
				return;
			case "standard":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.StandardTokenizer), options);
				return;
			case "thai":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.ThaiTokenizer), options);
				return;
			case "uax_url_email":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.UaxEmailUrlTokenizer), options);
				return;
			case "whitespace":
				JsonSerializer.Serialize(writer, value, typeof(Elastic.Clients.Elasticsearch.Serverless.Analysis.WhitespaceTokenizer), options);
				return;
			default:
				var type = value.GetType();
				JsonSerializer.Serialize(writer, value, type, options);
				return;
		}
	}
}

[JsonConverter(typeof(TokenizerInterfaceConverter))]
public partial interface ITokenizer
{
	public string? Type { get; }
}